package com.lyl.module.aop;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.lyl.module.api.service.LoginApiService;
import com.lyl.module.constant.ALIYUN_GLOBAL_VARIABLE;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * @author Mr.Luo
 * @date 2022-07-23 11:20
 * @desc 阿里云盘响应
 */
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class AliYunPanResponseAop {
    private final LoginApiService loginApiService;

    @Pointcut("execution(* com.lyl.module.api.client.FileApiClient.*(..))")
    public void pointcut(){}

    /**
     * 检查认证是否失败
     * @param pjp
     * @return
     */
    @Around(value = "pointcut()")
    public JSONObject around(ProceedingJoinPoint pjp){
        if (StrUtil.isBlank(ALIYUN_GLOBAL_VARIABLE.REFRESH_TOKEN)){
            log.error("当前账号未登录");
            throw new RuntimeException("当前账号未登录");
        }
        if (ObjectUtil.isNull(ALIYUN_GLOBAL_VARIABLE.NEXT_REFRESH_TOKEN_TIME) || DateUtil.date().isAfter(ALIYUN_GLOBAL_VARIABLE.NEXT_REFRESH_TOKEN_TIME)){
            loginApiService.refreshToken();
        }
        JSONObject result = execute(pjp);
        if (ObjectUtil.isNull(result) || "InvalidParameter.RefreshToken".equals(result.getStr("code"))){
            log.error("当前账号登录已过期，请重新登录");
            throw new RuntimeException("当前账号登录已过期，请重新登录");
        }
        if (ObjectUtil.isNull(result) || "AccessTokenInvalid".equals(result.getStr("code"))){
            loginApiService.refreshToken();
            log.info("刷新token");
            return execute(pjp);
        }
        return result;
    }

    private JSONObject execute(ProceedingJoinPoint pjp) {
        Object[] args = pjp.getArgs();
        JSONObject result = new JSONObject();
        try {
            result = (JSONObject) pjp.proceed(args);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return result;
    }
}
